package com.chapp.provider;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.util.Log;

public class DroidContentProvider extends ContentProvider{

	private static final String TAG = "DroidContentProvider";
	private static final String DATABASE_NAME = "droid.db";
	private static final int DATABASE_VERSION = 1;
	public static final String AUTHORITY = "com.chapp.provider.DroidContentProvider";
	private static final UriMatcher mURIMATCHER = buildUriMatcher();
	private static HashMap<String, String> artistProjectionMap;
	private static HashMap<String, String> locationProjectionMap;
	private static HashMap<String, String> venueProjectionMap;
	private static HashMap<String, String> eventProjectionMap;
	DatabaseHelper helper;
	public static final String TABLE_ARTIST = "artist";
	private static final String TABLE_LOCATION = "location";
	private static final String TABLE_VENUE = "venue";
	private static final String TABLE_EVENT = "event";
	
	private static class DatabaseHelper extends SQLiteOpenHelper {

		public DatabaseHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL("CREATE TABLE " + TABLE_ARTIST + " (" 
					+ " _id INTEGER PRIMARY KEY AUTOINCREMENT,"
					+ " name VARCHAR(255)," 
					+ " bio VARCHAR(255),"
					+ " image VARCHAR(255));");
			db.execSQL("CREATE TABLE "+TABLE_EVENT+" (" 
					+ " _id INTEGER PRIMARY KEY AUTOINCREMENT,"
					+ " title VARCHAR(255),"
					+ " description VARCHAR(255),"
					+ " artist VARCHAR(255),"
					+ " venue INTEGER,"
					+ " tickets VARCHAR(255),"
					+ " date VARCHAR(20),"
					+ " id_event VARCHAR(20),"
					+ " image VARCHAR(255));");
			db.execSQL("CREATE TABLE "+TABLE_VENUE+" (" 
					+ " _id INTEGER PRIMARY KEY AUTOINCREMENT," 
					+ " name VARCHAR(255)," 
					+ " location INTEGER ,"
					+ " url VARCHAR(255)," 
					+ " phone VARCHAR(20), " 
					+ " parent INTEGER, "
					+ " id_venue VARCHAR(20), "
					+ " image VARCHAR(255));");
			db.execSQL("CREATE TABLE " + TABLE_LOCATION + " (" 
					+ " _id INTEGER PRIMARY KEY AUTOINCREMENT,"
					+ " city VARCHAR(255),"
					+ " country VARCHAR(255),"
					+ " street VARCHAR(255),"
					+ " postalcode VARCHAR(255),"
					+ " lat VARCHAR(255),"
					+ " long VARCHAR(255));");
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
					+ newVersion + ", which will destroy all old data");
			db.execSQL("DROP TABLE IF EXISTS artist");
			onCreate(db);
		}
	}
	
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = helper.getWritableDatabase();
		String table = "";
		int count = 0;
		switch (mURIMATCHER.match(uri)) {
		case 1:
			table = TABLE_ARTIST;
			count = db.delete(table, selection, selectionArgs);
		break;
		case 2:
			table = TABLE_ARTIST;
			String select = "_id =?";
			String[] args = new String[] { uri.getLastPathSegment() };
			count = db.delete(table, select, args);
		break;
		case 3:
			table = TABLE_LOCATION;
			count = db.delete(table, selection, selectionArgs);
			break;
		case 4:
			table = TABLE_LOCATION;
			select = "_id =?";
			args = new String[] { uri.getLastPathSegment() };
			count = db.delete(table, select, args);
			break;
		case 5:
			table = TABLE_VENUE;
			count = db.delete(table, selection, selectionArgs);
			break;
		case 6:
			table = TABLE_VENUE;
			select = "id_venue =?";
			args = new String[] { uri.getLastPathSegment() };
			count = db.delete(table, select, args);
			break;
		case 7:
			table = TABLE_EVENT;
			count = db.delete(table, selection, selectionArgs);
			break;
		case 8:
			table = TABLE_EVENT;
			select = "id_event =?";
			args = new String[] { uri.getLastPathSegment() };
			count = db.delete(table, select, args);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
		return count;
	}

	private static UriMatcher buildUriMatcher() {
		UriMatcher uris = new UriMatcher(UriMatcher.NO_MATCH);
		uris.addURI(AUTHORITY, TABLE_ARTIST, 1);
		uris.addURI(AUTHORITY, TABLE_ARTIST+"/#", 2);
		uris.addURI(AUTHORITY, TABLE_LOCATION, 3);
		uris.addURI(AUTHORITY, TABLE_LOCATION+"/#", 4);
		uris.addURI(AUTHORITY, TABLE_VENUE, 5);
		uris.addURI(AUTHORITY, TABLE_VENUE+"/*", 6);
		uris.addURI(AUTHORITY, TABLE_EVENT, 7);
		uris.addURI(AUTHORITY, TABLE_EVENT+"/#", 8);
		
		uris.addURI(AUTHORITY, TABLE_ARTIST+"/*", 9);
		uris.addURI(AUTHORITY, TABLE_EVENT+"/*", 10);
		uris.addURI(AUTHORITY, TABLE_VENUE+"/#", 11);
		return uris;
	}

	@Override
	public String getType(Uri uri) {
		switch (mURIMATCHER.match(uri)) {
		case 1:
			return "vnd.android.cursor.dir/vnd.chapp.base.Artist";
		case 2:
			return "vnd.android.cursor.item/vnd.chapp.base.Artist";
		case 3:
			return "vnd.android.cursor.dir/vnd.chapp.base.Location";
		case 4:
			return "vnd.android.cursor.item/vnd.chapp.base.Location";
		case 5:
			return "vnd.android.cursor.dir/vnd.chapp.base.Venue";
		case 6:
			return "vnd.android.cursor.item/vnd.chapp.base.Venue";
		case 7:
			return "vnd.android.cursor.dir/vnd.chapp.base.Event";
		case 8:
			return "vnd.android.cursor.item/vnd.chapp.base.Event";
		case 9:
			return "vnd.android.cursor.item/vnd.chapp.base.Artist";
		case 10:
			return "vnd.android.cursor.item/vnd.chapp.base.Event";
		case 11:
			return "vnd.android.cursor.item/vnd.chapp.base.Venue";
		default:
			throw new IllegalArgumentException("Impossible return type. Unknown URI " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase db = helper.getWritableDatabase();
		String table = "";
		switch (mURIMATCHER.match(uri)) {
		case 1:
			table = TABLE_ARTIST;
		break;
		case 3:
			table = TABLE_LOCATION;
			break;
		case 5:
			table = TABLE_VENUE;
			break;
		case 7:
			table = TABLE_EVENT;
			break;
		case 9:
			table = TABLE_ARTIST;
			break;
		case 10:
			table = TABLE_EVENT;
			break;
		case 11:
			table = TABLE_VENUE;
			break;
		}
		if (table.equals("")){
			throw new SQLException("Unknow URI "+uri);
		}
		else{
			long rowId = db.insert(table, null, values);
			if (rowId > 0) {
				Uri noteUri = ContentUris.withAppendedId(uri, rowId);
				return noteUri;
			}
			throw new SQLException("Failed to insert row into " + uri);
		}
	}

	@Override
	public boolean onCreate() {
		helper = new DatabaseHelper(this.getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		
		String select = "";
		String args[];
		
		SQLiteDatabase db = helper.getWritableDatabase();

		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		switch (mURIMATCHER.match(uri)) {
		case 1:
			qb.setTables(TABLE_ARTIST);
			qb.setProjectionMap(artistProjectionMap);
			select = selection;
			args = selectionArgs;
			break;
		case 2:
			qb.setTables(TABLE_ARTIST);
			qb.setProjectionMap(artistProjectionMap);
			select = "_id =?";
			args = new String[] { uri.getLastPathSegment() };
			break;
		case 3:
			qb.setTables(TABLE_LOCATION);
			qb.setProjectionMap(locationProjectionMap);
			select = selection;
			args = selectionArgs;
			break;
		case 4:
			qb.setTables(TABLE_LOCATION);
			qb.setProjectionMap(locationProjectionMap);
			select = "_id =?";
			args = new String[] { uri.getLastPathSegment() };
			break;
		case 5:
			qb.setTables(TABLE_VENUE);
			qb.setProjectionMap(venueProjectionMap);
			select = "parent=?";
			args = new String[]{"0"};
			break;
		case 6:
			qb.setTables(TABLE_VENUE);
			qb.setProjectionMap(venueProjectionMap);
			select = "id_venue =?";
			args = new String[] { uri.getLastPathSegment() };
			break;
		case 7:
			qb.setTables(TABLE_EVENT);
			qb.setProjectionMap(eventProjectionMap);
			select = selection;
			args = selectionArgs;
			break;
		case 8:
			qb.setTables(TABLE_EVENT);
			qb.setProjectionMap(eventProjectionMap);
			select = "_id =?";
			args = new String[] { uri.getLastPathSegment() };
			break;
		case 9:
			qb.setTables(TABLE_ARTIST);
			qb.setProjectionMap(artistProjectionMap);
			select = "name =?";
			args = new String[] { uri.getLastPathSegment() };
			break;
		case 10:
			qb.setTables(TABLE_EVENT);
			qb.setProjectionMap(eventProjectionMap);
			select = "id_event =?";
			args = new String[] { uri.getLastPathSegment() };
			break;
		case 11:
			qb.setTables(TABLE_VENUE);
			qb.setProjectionMap(venueProjectionMap);
			select = "parent=?";
			args = new String[] { uri.getLastPathSegment() };
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		Cursor c = qb.query(db, projection, select, args, null, null, sortOrder);
		return c;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		return 0;
	}
	
	static {
		// Orden y valores como van a consultarse de la base de datos
		artistProjectionMap = new HashMap<String, String>();
		artistProjectionMap.put("_id", "_id");
		artistProjectionMap.put("name", "name");
		artistProjectionMap.put("bio", "bio");
		artistProjectionMap.put("image", "image");
		
		locationProjectionMap = new HashMap<String, String>();
		locationProjectionMap.put("_id", "_id");
		locationProjectionMap.put("city", "city");
		locationProjectionMap.put("country", "country");
		locationProjectionMap.put("street", "street");
		locationProjectionMap.put("postalcode", "postalcode");
		locationProjectionMap.put("lat", "lat");
		locationProjectionMap.put("long", "long");
		
		venueProjectionMap = new HashMap<String, String>();
		venueProjectionMap.put("name", "name");
		venueProjectionMap.put("location", "location");
		venueProjectionMap.put("url", "url");
		venueProjectionMap.put("phone", "phone");
		venueProjectionMap.put("image", "image");
		venueProjectionMap.put("parent", "parent");
		venueProjectionMap.put("id_venue", "id_venue");
		
		eventProjectionMap = new HashMap<String, String>();
		eventProjectionMap.put("_id", "_id");
		eventProjectionMap.put("title", "title");
		eventProjectionMap.put("artist", "artist");
		eventProjectionMap.put("description", "description");
		eventProjectionMap.put("venue", "venue");
		eventProjectionMap.put("tickets", "tickets");
		eventProjectionMap.put("date", "date");
		eventProjectionMap.put("image", "image");
		eventProjectionMap.put("id_event", "id_event");
	}

}
